﻿using System;
using System.Collections.Generic;
using System.Text;
using HAVNet.Core;


namespace HAVNet.Intros.AST
{
    public class ASTMemberDeclMethod : ASTMemberDeclStruct
    {
        ASTTypeParamList        _typeParamList  = null;
        ASTFormalParamList      _formalParamList= null;
        ASTTypeConstraintList   _constraints    = null;

        public bool                 isPartial       { get; set; }
        public ASTMemberName        name            { get; set; }
        public ASTType              returnType      { get; set; }
        public ASTTypeParamList     typeParamList   { get { if (null == _typeParamList) _typeParamList = new ASTTypeParamList(); return _typeParamList; } }
        public ASTFormalParamList   formalParamList { get { if (null == _formalParamList) _formalParamList = new ASTFormalParamList(); return _formalParamList; } }
        public ASTTypeConstraintList constraints    { get { if (null == _constraints) _constraints = new ASTTypeConstraintList(); return _constraints; } }
        public ASTBlock             block           { get; set; }

        public override string ToString ()
        {
            string sAttrs = ((null == _attrGroups) ? "" : _attrGroups.ToString() + Environment.NewLine);

            string sMods = "";

            if (Mods.has(modifiers, Mods.newMod         )) sMods += "new ";
            if (Mods.has(modifiers, Mods.publicMod      )) sMods += "public ";
            if (Mods.has(modifiers, Mods.protectedMod   )) sMods += "protected ";
            if (Mods.has(modifiers, Mods.internalMod    )) sMods += "internal ";
            if (Mods.has(modifiers, Mods.privateMod     )) sMods += "private ";
            if (Mods.has(modifiers, Mods.unsafeMod      )) sMods += "unsafe ";
            if (Mods.has(modifiers, Mods.staticMod      )) sMods += "static ";
            if (Mods.has(modifiers, Mods.virtualMod     )) sMods += "virtual ";
            if (Mods.has(modifiers, Mods.sealedMod      )) sMods += "sealed ";
            if (Mods.has(modifiers, Mods.overrideMod    )) sMods += "override ";
            if (Mods.has(modifiers, Mods.abstractMod    )) sMods += "abstract ";
            if (Mods.has(modifiers, Mods.externMod      )) sMods += "extern ";

            string sReturnType      = returnType.ToString   () + " ";
            string sTypeParamList   = Lazy.toStringNN       (_typeParamList, "");
            string sFormalParams    = "(" + Lazy.toStringNN (_formalParamList, "") + ")";
            string sConstraints     = " " +  Lazy.toStringNN(_constraints, "") + Environment.NewLine;
            string sBlock           = (block == null ? ";" : block.ToString());
            
            return string.Format (
                "{0}{1}{2}{3}{4}{5}{6}{7}{8}",
                    sAttrs,
                    sMods,
                    (isPartial ? " partial " : ""),
                    sReturnType,
                    name,
                    sTypeParamList,
                    sFormalParams,
                    sConstraints,
                    sBlock + Environment.NewLine
            );
        }
    }
}
